package com.cuoyi.coupon.mall.config;

/**
 * @author zhang.cheng
 * 2022/3/18 11:33 PM
 */

import com.cuoyi.coupon.mall.common.ApiResult;
import com.cuoyi.coupon.mall.common.BusinessException;
import com.cuoyi.coupon.mall.enums.ErrorEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.ServletRequestBindingException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;

import java.util.Iterator;
import java.util.List;

@Slf4j
@ControllerAdvice
public class GlobalErrorHandler {

    public GlobalErrorHandler() {
    }

    @ResponseBody
    @ExceptionHandler({BusinessException.class})
    public ApiResult<Void> businessException(BusinessException e) {
        log.error("#businessException:", e);
        return ApiResult.error(e.getCode(), e.getMessage());
    }

    @ResponseBody
    @ExceptionHandler({Exception.class})
    public ApiResult<Void> exception(Exception e) {
        log.error("#exceptionHandler:", e);
        return ApiResult.error(ErrorEnum.SYSTEM_ERROR.code(), ErrorEnum.SYSTEM_ERROR.message());
    }

    @ResponseBody
    @ExceptionHandler({MissingServletRequestParameterException.class})
    public ApiResult<Void> missingServletRequestParameterException(MissingServletRequestParameterException e) {
        log.error("#missingServletRequestParameterException:", e);
        return ApiResult.error(ErrorEnum.PARAMS_ERROR.code(), e.getMessage());
    }

    @ResponseBody
    @ExceptionHandler({ServletRequestBindingException.class})
    public ApiResult<Void> servletRequestBindingExceptionHandler(ServletRequestBindingException e) {
        log.error("#servletRequestBindingExceptionHandler:", e);
        return ApiResult.error(ErrorEnum.PARAMS_ERROR.code(), e.getMessage());
    }

    @ResponseBody
    @ExceptionHandler({HttpMessageNotReadableException.class})
    public ApiResult<Void> httpMessageNotReadableException(HttpMessageNotReadableException e) {
        log.error("#httpMessageNotReadableException:", e);
        return ApiResult.error(ErrorEnum.PARAMS_ERROR.code(), ErrorEnum.PARAMS_ERROR.message());
    }

    @ResponseBody
    @ExceptionHandler({MethodArgumentTypeMismatchException.class})
    public ApiResult<Void> methodArgumentTypeMismatchException(MethodArgumentTypeMismatchException e) {
        log.error("#methodArgumentTypeMismatchException:", e);
        return ApiResult.error(ErrorEnum.PARAMS_ERROR.code(), "[" + e.getName() + "] 参数类型不匹配");
    }

    @ResponseBody
    @ExceptionHandler({HttpRequestMethodNotSupportedException.class})
    public ApiResult<Void> multipartExceptionExceptionHandler(HttpRequestMethodNotSupportedException e) {
        log.error("#multipartExceptionExceptionHandler:", e);
        return ApiResult.error(ErrorEnum.PARAMS_ERROR.code(), e.getMessage());
    }

    @ResponseBody
    @ExceptionHandler({MethodArgumentNotValidException.class})
    public ApiResult<Void> methodArgumentNotValidException(MethodArgumentNotValidException e) {
        log.error("#methodArgumentNotValidException:", e);
        return acquireCommonExceptionHandler(e.getBindingResult().getFieldErrors());

    }

    @ResponseBody
    @ExceptionHandler({BindException.class})
    public ApiResult<Void> bindExceptionHandler(BindException e) {
        log.error("#bindExceptionHandler:", e);
        return acquireCommonExceptionHandler(e.getFieldErrors());
    }


    private ApiResult<Void> acquireCommonExceptionHandler(List<FieldError> errors) {
        StringBuilder builder = new StringBuilder();
        Iterator var4 = errors.iterator();
        while (var4.hasNext()) {
            FieldError error = (FieldError) var4.next();
            String field = error.getField();
            String message = error.getDefaultMessage();
            builder.append("[").append(field).append("]").append(message).append("; ");
        }
        return ApiResult.error(ErrorEnum.PARAMS_ERROR.code(), builder.toString());
    }
}
